﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BukkitSharp.org.bukkit.block;
//using BukkitSharp.org.bukkit.Chunk;
//using BukkitSharp.org.bukkit.Location;
//using BukkitSharp.org.bukkit.Material;
//using BukkitSharp.org.bukkit.World;
//using BukkitSharp.org.bukkit.material.MaterialData;
//using BukkitSharp.org.bukkit.metadata.Metadatable;


namespace BukkitSharp.org.bukkit.block
{
    public interface BlockState : Metadatable
    {
        /**
         * Gets the block represented by this BlockState
         *
         * @return Block that this BlockState represents
         */
        Block getBlock();

        /**
         * Gets the metadata for this block
         *
         * @return block specific metadata
         */
        MaterialData getData();

        /**
         * Gets the type of this block
         *
         * @return block type
         */
        Material getType();

        /**
         * Gets the type-id of this block
         *
         * @return block type-id
         */
        int getTypeId();

        /**
         * Gets the light level between 0-15
         *
         * @return light level
         */
        byte getLightLevel();

        /**
         * Gets the world which contains this Block
         *
         * @return World containing this block
         */
        World getWorld();

        /**
         * Gets the x-coordinate of this block
         *
         * @return x-coordinate
         */
        int getX();

        /**
         * Gets the y-coordinate of this block
         *
         * @return y-coordinate
         */
        int getY();

        /**
         * Gets the z-coordinate of this block
         *
         * @return z-coordinate
         */
        int getZ();

        /**
         * Gets the location of this block
         *
         * @return location
         */
        Location getLocation();

        /**
         * Stores the location of this block in the provided Location object.<br />
         * If the provided Location is null this method does nothing and returns null.
         *
         * @return The Location object provided or null
         */
        Location getLocation(Location loc);

        /**
         * Gets the chunk which contains this block
         *
         * @return Containing Chunk
         */
        Chunk getChunk();

        /**
         * Sets the metadata for this block
         *
         * @param data New block specific metadata
         */
        void setData(MaterialData data);

        /**
         * Sets the type of this block
         *
         * @param type Material to change this block to
         */
        void setType(Material type);

        /**
         * Sets the type-id of this block
         *
         * @param type Type-Id to change this block to
         * @return Whether it worked?
         */
        bool setTypeId(int type);

        /**
         * Attempts to update the block represented by this state, setting it to the
         * new values as defined by this state.
         * <p />
         * This has the same effect as calling update(false). That is to say,
         * this will not modify the state of a block if it is no longer the same
         * type as it was when this state was taken. It will return false in this
         * eventuality.
         *
         * @return true if the update was successful, otherwise false
         * @see #update(boolean)
         */
        bool update();

        /**
         * Attempts to update the block represented by this state, setting it to the
         * new values as defined by this state.
         * <p />
         * Unless force is true, this will not modify the state of a block if it is
         * no longer the same type as it was when this state was taken. It will return
         * false in this eventuality.
         * <p />
         * If force is true, it will set the type of the block to match the new state,
         * set the state data and then return true.
         *
         * @param force true to forcefully set the state
         * @return true if the update was successful, otherwise false
         */
        bool update(bool force);

        /**
         * @return The data as a raw byte.
         */
        public byte getRawData();

        /**
         * @param data The new data value for the block.
         */
        public void setRawData(byte data);
    }
}
